package com.zytech.zspider.task.impl.http;

import com.zytech.modules.lang.Langs;

import java.net.URLEncoder;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author siuming
 */
public final class HttpTaskRequestUrlBuilder {

    /**
     * @param baseurl
     * @param params
     * @return
     */
    public static String buildQueryUrl(String baseurl, Map<String, String> params) {
        return HttpTaskRequestUrlBuilder.buildQueryUrl(baseurl, "UTF-8", params);
    }

    /**
     * @param baseurl
     * @param charset
     * @param params
     * @return
     */
    public static String buildQueryUrl(String baseurl, String charset, Map<String, String> params) {

        String url = transformBaseUrl(baseurl, charset);
        if (params.isEmpty()) {
            return url;
        }

        // clean frament.
        if (url.indexOf("#") > 0) {
            url = url.substring(0, url.indexOf("#"));
        }

        int qp = url.indexOf("?");
        if (qp == -1) {
            url = url + "?";
        } else if (qp < url.length() - 1 && !url.endsWith("&")) {// has params and not endwith '&'
            url = url + "&";
        }

        StringBuilder buf = new StringBuilder().append(url);
        for (Map.Entry<String, String> entry : params.entrySet()) {
            buf.append(urlEncode(entry.getKey(), charset)).append("=");
            buf.append(urlEncode(entry.getValue(), charset)).append("&");
        }
        return buf.toString();
    }

    private static String transformBaseUrl(String baseurl, String charset) {
        Matcher m = Pattern.compile("[^\\x00-\\x7f[\\s]]").matcher(baseurl);
        StringBuffer buf = new StringBuffer();
        while (m.find()) {
            m.appendReplacement(buf, urlEncode(m.group(), charset));
        }
        m.appendTail(buf);
        return buf.toString();
    }

    private static String urlEncode(String param, String charset) {
        try {

            return URLEncoder.encode(param, charset);
        } catch (Exception e) {
            throw Langs.toUncheck(e);
        }
    }

    private HttpTaskRequestUrlBuilder() {
    }
}
